home *** CD-ROM | disk | FTP | other *** search
- #include <fcntl.h>
- #include <stat.h>
- #include <types.h>
- #include <errno.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include "lib.h"
- #define __MINT__
- #include <mintbind.h>
-
-
- extern int __mint;
-
- #if defined(DEBUG)
- # include <stdio.h>
- #endif
-
- #ifndef _COMPILER_H
- # include <compiler.h>
- #endif
- __EXTERN char *tmpnam __PROTO((char *buf));
-
- /**
- ** (sjk)++ These routines simulate a eunchs pipe() call using temporary
- ** files. A linked list of type *_pipe is kept as to allow as
- ** many open pipes as there are valid file descriptors. The only
- ** problem is that the pipe is initiallialy opened for writing,
- ** and all output must be done to the pipe, then call pipeclose(fd);
- ** and it sets up the pipe for reading. After all input is done,
- ** call pipeclose(fd) again and this will close the pipe and delete
- ** the temporary file that the pipe created.
- **
- **/
-
- struct _pipe { char p_name[40];
- char flag; /* "r"-->read, "w"-->write */
- int file_des;
- struct _pipe *next;
- };
- static struct _pipe *__pipes = NULL;
- static int del_list (struct _pipe *);
-
- __EXTERN int pipeclose __PROTO((int fd));
- extern int (*pipeclose_p) __PROTO((int fd));
-
- /*---------------------------------------------------------------------------*/
- /* Make a pipe, open the tempory file, set it up for writing, add the pipe */
- /* descriptor to our linked list of pipes, and return. */
- /*---------------------------------------------------------------------------*/
- int pipe(fildes)
- int fildes[2];
- { int fd;
- char name[40];
- struct _pipe *p;
-
- tmpnam(name); /* Make a temporary file name. */
-
- /*----------------------------------------------*/
- /* Open the pipe for reading and writing. */
- /*----------------------------------------------*/
- fd = open(name,O_CREAT | O_TRUNC | O_RDWR | O_PIPE, 0644);
-
- #if defined(DEBUG)
- fprintf(stderr,"opened pipe - fd : %d.\n",fd);
- #endif
-
- if (fd < 0)
- #if defined(DEBUG)
- fprintf(stderr,"fd returns : %d! PIPE(%s) failed.\n",fd, name);
- #else
- /* nothing */;
- #endif
- else
- { /*------------------------------------------*/
- /* Get a pipe description block and */
- /* put in the (1)file name, */
- /* (2)file descriptor, */
- /* (3)file mode = "w". */
- /*------------------------------------------*/
- /*-------------------------------------------------------------------*/
- p = (struct _pipe *)malloc(sizeof (struct _pipe));
- strcpy(p->p_name,name); /* fill in name. */
- p->flag = 'w'; /* initially for write. */
- p->file_des = fd; /* fill in the pipe descriptor. */
- if(!__pipes)
- pipeclose_p = pipeclose; /* patch in addr of close routine */
- /*-------------------------------------------------------------------*/
- p->next = __pipes; /* Link to our list of open pipes. */
- __pipes = p;
- /*-------------------------------------------------------------------*/
- fildes[0] = fildes[1] = fd; /* we fill in fildes[]. */
- if (__mint)
- (void) Fcntl(fd,0L,2); /* Make fd shared across Pexecs() */
- }
- return(fd); /* Return the file descriptor. */
- }
-
- /*---------------------------------------------------------------------*/
- /* close a pipe, if the pipe was open for writing, set it to a read */
- /* read pipe, and lseek to the begining of the pipe. if it was open */
- /* for reading then close the pipe, delete the temporary file, and */
- /* remove the pipe descriptor from the __pipes linked list. */
- /*---------------------------------------------------------------------*/
- int
- pipeclose(fd)
- int fd;
- { struct _pipe *p;
- int ifd;
- for (p=__pipes; p; p=p->next)
- { if (fd == p->file_des)
- {
- #if defined(DEBUG)
- fprintf(stderr,"Deleting pipe - mode : %c, fd : %d\n",p->flag,fd);
- #endif
- if (p->flag == 'r')
- { int res;
- ifd = __OPEN_INDEX(fd);
- __open_stat[ifd].pipe = 0; /* So close wont recurse */
- res = close(fd);
- unlink(p->p_name); /* Delete it. */
- del_list(p); /* delete from the list. */
- return(res);
- }
- else
- if (p->flag =='w')
- { p->flag = 'r'; /* now make it read. */
- lseek(p->file_des,0,SEEK_SET); /* read from the start. */
- return(0);
- }
- }
- }
- #if defined(DEBUG)
- fprintf(stderr,"attempt to close nonexistant pipe.\n");
- #endif
- return(-1);
- }
-
- /*---------------------------------------------------------------------*/
- /* delete a pipe descriptor from our list of pipes rooted ar __pipes. */
- /*---------------------------------------------------------------------*/
- static int del_list(p)
- struct _pipe *p;
- { struct _pipe *q,*r;
-
- if (p == __pipes) /* Is it the first element? */
- { __pipes = p->next;
- free(p);
- return(0);
- }
- else
- { r = __pipes->next; q = __pipes; /* No it is interior. */
- for (; r; r = r->next)
- { if (r == p)
- { q->next = r->next; /* pass over it. */
- free(r); /* free its space. */
- return(0); /* go home. */
- }
- q = r; /* update trailing pointer. */
- }
- }
- #if defined(DEBUG)
- fprintf(stderr,"Attempt to delete a nonexisting pipe form list (__pipes).");
- #endif
- return(-1);
- }
-